home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-13 / ae_14.zip / AE4.PAS < prev    next >
Pascal/Delphi Source File  |  1991-03-12  |  29KB  |  708 lines

  1. unit AE4 ;
  2.  
  3. {$B-}
  4. {$I-}
  5. {$S+}
  6. {$V-}
  7.  
  8. interface
  9.  
  10. uses Crt,Dos,Printer,AE0,AE1,AE2,AE3 ;
  11.  
  12. function CopyBlock : boolean ;
  13. procedure DeleteBlock ;
  14. procedure InsertBlock ;
  15. procedure PrintBlock (Buffer:WsBufptr ; BlockStart,BlockEnd:word ) ;
  16. procedure InsertFile (Filename:PathStr; P:Position) ;
  17. procedure LoadFile (Filename:PathStr) ;
  18. function GetFileFromList (Name:PathStr) : PathStr ;
  19. procedure InsertSpaces (var P:Position ; NrOfSpaces:word) ;
  20. procedure InsertCRLF (var P:Position) ;
  21. procedure RedrawScreen ;
  22. procedure AlterSetup ;
  23.  
  24. implementation
  25.  
  26. {-----------------------------------------------------------------------------}
  27. { Copies the block in the current workspace to the paste buffer. If no block  }
  28. { is indicated or if the block is too large for the paste buffer, an error    }
  29. { message is given, and the function result will be False.                    }
  30. {-----------------------------------------------------------------------------}
  31.  
  32. function CopyBlock : boolean ;
  33.  
  34. var Result : boolean ;
  35.  
  36. begin
  37. Result := False ;
  38. with Workspace[CurrentWsnr] do
  39.      begin
  40.      if (Mark > 0)
  41.         then begin
  42.              if Mark < CurPos.Index
  43.                 then begin
  44.                      if (CurPos.Index - Mark) > PasteBufSize
  45.                         then ErrorMessage (4)
  46.                         else begin
  47.                              PasteBufferSize := CurPos.Index - Mark ;
  48.                              Move (Buffer^[Mark],PasteBuffer^[1],
  49.                                    PasteBufferSize) ;
  50.                              Result := True ;
  51.                              end ;
  52.                      end
  53.                 else begin
  54.                      if (Mark - CurPos.Index) > PasteBufSize
  55.                         then ErrorMessage (4)
  56.                         else begin
  57.                              PasteBufferSize := Mark - CurPos.Index ;
  58.                              Move (Buffer^[CurPos.Index],PasteBuffer^[1],
  59.                                    PasteBufferSize) ;
  60.                              Result := True ;
  61.                              end ;
  62.                      end ;
  63.              end
  64.         else ErrorMessage (5) ;
  65.      end ; { of with }
  66. CopyBlock := Result ;
  67. end ;
  68.  
  69. {-----------------------------------------------------------------------------}
  70. { Deletes the block from the current workspace.                               }
  71. {-----------------------------------------------------------------------------}
  72.  
  73. procedure DeleteBlock ;
  74.  
  75. var OldCurPosIndex : word ;
  76.  
  77. begin
  78. with Workspace[CurrentWsnr] do
  79.      begin
  80.      if Mark > 0
  81.         then begin
  82.              if Mark < CurPos.Index
  83.                 then begin
  84.                      { if Mark is before CurPos: exchange positions }
  85.                      OldCurPosIndex := CurPos.Index ;
  86.                      SkipUp (CurPos,OldCurPosIndex-Mark) ;
  87.                      Mark := OldCurPosIndex ;
  88.                      end ;
  89.              Shrink (CurPos.Index,Mark-CurPos.Index) ;
  90.              Mark := 0 ;
  91.              end ;
  92.      end ;
  93. end ;
  94.  
  95. {-----------------------------------------------------------------------------}
  96. { Inserts the contents of the paste buffer into the current workspace at      }
  97. { position CurPos. If successful, Mark will be pointing to the end of the     }
  98. { inserted block, and CurPos to the start.                                    }
  99. {-----------------------------------------------------------------------------}
  100.  
  101. procedure InsertBlock ;
  102.  
  103. begin
  104. with Workspace[CurrentWsnr] do
  105.      begin
  106.      if Grow (CurPos.Index,PasteBufferSize)
  107.         then Move (PasteBuffer^[1],Buffer^[CurPos.Index],PasteBufferSize) ;
  108.      end ; { of with }
  109. end ;
  110.  
  111. {-----------------------------------------------------------------------------}
  112. { Dumps a block (indicated by BlockStart and BlockEnd) to the printer.        }
  113. { If enabled by Setup, form feeds, left and top margins and page numbers      }
  114. { are added.                                                                  }
  115. {-----------------------------------------------------------------------------}
  116.  
  117. procedure PrintBlock (Buffer:WsBufptr ; BlockStart,BlockEnd:word ) ;
  118.  
  119. var Counter,IndexCounter,LineCounter,PageCounter,LinesPerPage : word ;
  120.     DummyKey : word ;
  121.     AbortPrint : boolean ;
  122.  
  123. begin
  124. LineCounter := 1 ;
  125. PageCounter := 1 ;
  126. { LinesPerPagecontains number of text lines on a page }
  127. LinesPerPage := Config.Setup.PageLength ;
  128. if Config.Setup.PrintPagenrs then Dec (LinesPerPage,2) ;
  129. Message ('Printing. Press any key to interrupt') ;
  130. AbortPrint := False ;
  131. IndexCounter := BlockStart ;
  132. { write left margin of first line }
  133. Write (Lst,'':Config.Setup.LeftMargin) ;
  134. repeat if LineCounter = 1
  135.           then begin
  136.                { skip top margin }
  137.                for Counter := 1 to Config.Setup.TopMargin do
  138.                    Writeln (Lst) ;
  139.                LineCounter := Config.Setup.TopMargin + 1 ;
  140.                Write (Lst,'':Config.Setup.LeftMargin) ;
  141.                end ;
  142.        Write (Lst,Buffer^[IndexCounter]) ;
  143.        if Buffer^[IndexCounter] = CR
  144.           then begin
  145.                Inc (LineCounter) ;
  146.                { write left margin }
  147.                Write (Lst,'':Config.Setup.LeftMargin) ;
  148.                end ;
  149.        if ((LineCounter > LinesPerPage) or (Buffer^[IndexCounter] = FF)) and
  150.           (Config.Setup.PageLength > 0)
  151.           then begin
  152.                { end current page and start new one }
  153.                if Config.Setup.PrintPagenrs
  154.                   then begin
  155.                        Writeln (Lst) ; Writeln (Lst) ;
  156.                        Write (Lst,'Pag ',PageCounter:2) ;
  157.                        end ;
  158.                Write (Lst,FF) ;
  159.                LineCounter := 1 ;
  160.                Inc (PageCounter) ;
  161.                { write left margin }
  162.                Write (Lst,'':Config.Setup.LeftMargin) ;
  163.                end ;
  164.        Inc (IndexCounter) ;
  165.        CheckDiskError ;
  166.        AbortPrint := (DiskError <> 0) ;
  167.        if KeyPressed
  168.           then begin
  169.                ClearKeyBuffer ;
  170.                { ask for confirmation }
  171.                AbortPrint := Answer ('Abort printing?') ;
  172.                if not AbortPrint
  173.                   then Message ('Printing. Press any key to interrupt') ;
  174.                end ;
  175. until (IndexCounter > BlockEnd) or AbortPrint ;
  176. if (Config.Setup.PrintPagenrs) and (not KeyPressed)
  177.    then begin
  178.         { end last page: move to end of page and print page number }
  179.         for Counter := LineCounter to (LinesPerPage+1) do
  180.             Writeln (Lst) ;
  181.         Write (Lst,'Pag ',PageCounter:2) ;
  182.         Write (Lst,FF) ;
  183.         CheckDiskError ;
  184.         end ;
  185. if AbortPrint
  186.    then Message ('Printing aborted')
  187.    else Message ('Printing completed') ;
  188. end ;
  189.  
  190. {-----------------------------------------------------------------------------}
  191. { Inserts the file <Filename> into the current workspace at position P.       }
  192. {-----------------------------------------------------------------------------}
  193.  
  194. procedure InsertFile (Filename:PathStr ; P:Position) ;
  195.  
  196. var F : file ;
  197.     Size,BytesToRead,AvailableSpace : longint ;
  198.     Counter : word ;
  199.  
  200. begin
  201. Assign (F,Filename) ;
  202. Reset (F,1) ;
  203. CheckDiskError ;
  204. if (DiskError = 0)
  205.    then begin
  206.         Size := FileSize (F) ;
  207.         with Workspace[CurrentWsnr] do
  208.              begin
  209.              BytesToRead := Size ;
  210.              AvailableSpace := WsBufSize - BufferSize ;
  211.              if BytesToRead > AvailableSpace
  212.                 then BytesToRead := AvailableSpace ;
  213.              if Grow (P.Index,BytesToRead)
  214.                 then begin
  215.                      { double reset: first to measure file size (record }
  216.                      { size 1), second to read file }
  217.                      Reset (F,BytesToRead) ;
  218.                      Message ('Reading file '+Filename) ;
  219.                      BlockRead (F,Buffer^[P.Index],1) ;
  220.                      CheckDiskError ;
  221.                      Mark := P.Index + BytesToRead ;
  222.                      { check for EndOfFile char }
  223.                      Counter := 0 ;
  224.                      while (Buffer^[P.Index+Counter] <> EF)
  225.                            and (Counter < BytesToRead) do
  226.                            Inc (Counter) ;
  227.                      { delete stuff after first EOF char }
  228.                      Shrink (P.Index+Counter,BytesToRead-Counter) ;
  229.                      Message ('') ;
  230.                      end ; { of if }
  231.              if Size > BytesToRead
  232.                 then { warning: file too large to load completely }
  233.                      ErrorMessage (7) ;
  234.              Close (F) ;
  235.              end ; { of with }
  236.         end ; { of if }
  237. end ; { of procedure }
  238.  
  239. {-----------------------------------------------------------------------------}
  240. { Loads the file <Filename> into the current workspace, resetting all         }
  241. { variables involved. If <Filename> is empty, then no file is loaded.         }
  242. {-----------------------------------------------------------------------------}
  243.  
  244. procedure LoadFile (Filename:PathStr) ;
  245.  
  246. begin
  247. ClearWorkspace(CurrentWsnr) ;
  248. if Length(FileName) > 0
  249.    then with Workspace[CurrentWsnr] do
  250.              begin
  251.              Name := FExpand (Filename) ;
  252.              InsertFile (Name,CurPos) ;
  253.              Mark := Inactive ;
  254.              ChangesMade := False ;
  255.              end ;
  256. end ;
  257.  
  258. {-----------------------------------------------------------------------------}
  259. { Displays a list with files, from which the user                             }
  260. { can then make a choice, using the cursor and Return keys.                   }
  261. { Cursor shape and position and screen contents are saved, and                }
  262. { restored on exit.                                                           }
  263. {-----------------------------------------------------------------------------}
  264.  
  265. function GetFileFromList (Name:PathStr) : PathStr ;
  266.  
  267. var OldXpos,OldYpos,OldCursorType,Counter : byte ;
  268.     OldAttr,NormAttr,SelectAttr : byte ;
  269.     OldDisplayContents : ScreenBlockPtr ;
  270.     SelectKey : word ;
  271.     FileList : array[1..MaxFileListLength] of FilenameStr ;
  272.     FirstVisibleFile,SelectedFile,FileListLength : byte ;
  273.     SR : SearchRec ;
  274.     Mask : FilenameStr ;
  275.     Dir,OldCurrentDir : DirStr ;
  276.     Fname : NameStr ;
  277.     Fext : ExtStr ;
  278.  
  279. begin
  280. GetDir (0,OldCurrentDir) ;
  281. { split pathname into directory and mask }
  282. FSplit (FExpand(Name),Dir,Fname,Fext) ;
  283. Mask := Fname + Fext ;
  284. if Length(Dir) > 3
  285.    then Delete (Dir,Length(Dir),1) ;
  286. ChDir (Dir) ;
  287. CheckDiskError ;
  288. { save old screen settings }
  289. OldXpos := WhereX ;
  290. OldYpos := WhereY ;
  291. OldCursorType := GetCursor ;
  292. OldAttr := TextAttr ;
  293. { new screen settings }
  294. SetCursor (Inactive) ;
  295. NormAttr := ScreenColorArray[Config.Setup.ScreenColors].NormAttr ;
  296. SelectAttr := ScreenColorArray[Config.Setup.ScreenColors].BlockAttr ;
  297. TextAttr := NormAttr ;
  298. { save old screen contents and draw frame for file list }
  299. SaveArea (60,2,75,23,OldDisplayContents) ;
  300. PutFrame (60,2,75,23,Quasi3DFrame) ;
  301. ClearArea (61,3,74,22) ;
  302. repeat Counter := 1 ;
  303.        Message ('Searching ...') ;
  304.        { build file list }
  305.        FindFirst (Mask,ReadOnly+Archive,SR) ;
  306.        while (DosError = 0) and (Counter < (MaxFileListLength-1)) do
  307.              begin
  308.              FileList[Counter] := SR.Name ;
  309.              FindNext (SR) ;
  310.              Inc (Counter) ;
  311.              end ;
  312.        { add directories }
  313.        FindFirst ('*.*',Directory,SR) ;
  314.        while (DosError = 0) and (Counter <= MaxFileListLength) do
  315.              begin
  316.              if ((SR.Attr and Directory) <> 0) and
  317.                 (SR.Name <> '.')
  318.                 then begin
  319.                      FileList[Counter] := '»' + SR.Name ;
  320.                      Inc (Counter) ;
  321.                      end ;
  322.              FindNext (SR) ;
  323.              end ;
  324.        Message ('Select file from list with ,,PgUp PgDn or ' +
  325.                 'press first letter. Enter to load') ;
  326.        FileListLength := Counter - 1 ;
  327.        FirstVisibleFile := 1 ;
  328.        SelectedFile := 1 ;
  329.        repeat if FirstVisibleFile > SelectedFile
  330.                  then FirstVisibleFile := SelectedFile ;
  331.               if (SelectedFile-FirstVisibleFile) > 19
  332.                  then FirstVisibleFile := SelectedFile - 19 ;
  333.               for Counter := FirstVisibleFile to (FirstVisibleFile+19) do
  334.                   begin
  335.                   if Counter = SelectedFile
  336.                      then TextAttr := SelectAttr
  337.                      else TextAttr := NormAttr ;
  338.                   GotoXY (61,Counter-FirstVisibleFile+3) ;
  339.                   if Counter <= FileListLength
  340.                      then Write (' ',FileList[Counter],
  341.                                  ' ':(13-Length(FileList[Counter])))
  342.                      else Write (' ':14) ;
  343.                   end ;
  344.               SelectKey := ReadKeyNr ;
  345.               case SelectKey of
  346.                    328 : { up    } if SelectedFile > 1
  347.                                       then Dec (SelectedFile) ;
  348.                    336 : { down  } if SelectedFile < FileListLength
  349.                                       then Inc (SelectedFile) ;
  350.                    329 : { PgUp  } if SelectedFile > 19
  351.                                       then Dec (SelectedFile,19)
  352.                                       else SelectedFile := 1 ;
  353.                    337 : { PgDn  } if SelectedFile < (FileListLength-19)
  354.                                       then Inc (SelectedFile,19)
  355.                                       else SelectedFile := FileListLength ;
  356.                    388 : { ^PgUp } SelectedFile := 1 ;
  357.                    374 : { ^PgDn } SelectedFile := FileListLength ;
  358.                    32..127   : begin
  359.                                { select by pressing first letter of name }
  360.                                Counter := SelectedFile + 1 ;
  361.                                while (not ((FileList[Counter][1] =
  362.                                             UpCase (Chr(SelectKey))) or
  363.                                            ((FileList[Counter][1] = '»') and
  364.                                             (FileList[Counter][2] =
  365.                                              UpCase (Chr(SelectKey))))))
  366.                                      and
  367.                                      (Counter <= FileListLength)
  368.                                      do Inc (Counter) ;
  369.                                if Counter <= FileListLength
  370.                                   then SelectedFile := Counter ;
  371.                                end ;
  372.                    ReturnKey : ;
  373.                    EscapeKey : EscPressed := true ;
  374.                    else        WarningBeep ; { invalid key }
  375.                    end ; { of case }
  376.        until (SelectKey = ReturnKey) or EscPressed ;
  377.        if (SelectKey = ReturnKey) and (FileList[SelectedFile][1] = '»')
  378.           then ChDir (Copy(FileList[SelectedFile],2,8)) ;
  379. until (FileList[SelectedFile][1] <> '»') or EscPressed ;
  380. { restore screen }
  381. Message ('') ;
  382. RestoreArea (60,2,75,23,OldDisplayContents) ;
  383. TextAttr := OldAttr ;
  384. GotoXY (OldXpos,OldYpos) ;
  385. SetCursor (OldCursorType) ;
  386. { construct full pathname from filename + directory }
  387. if EscPressed
  388.    then GetFileFromList := Name
  389.    else begin
  390.         GetDir (0,Dir) ;
  391.         if Dir[Length(Dir)] <> '\' then Dir := Dir + '\' ;
  392.         GetFileFromList := Dir + FileList[SelectedFile] ;
  393.         end ;
  394. ChDir (OldCurrentDir) ;
  395. end ;
  396.  
  397. {-----------------------------------------------------------------------------}
  398. { Insert a number of spaces into the current workspace at position P.         }
  399. { On exit, P will point to the position right after the last space.           }
  400. {-----------------------------------------------------------------------------}
  401.  
  402. procedure InsertSpaces (var P:Position ; NrOfSpaces:word) ;
  403.  
  404. begin
  405. with Workspace[CurrentWsnr] do
  406.      begin
  407.      if Grow (P.Index,NrOfSpaces)
  408.         then begin
  409.              FillChar (Buffer^[P.Index],NrOfSpaces,' ') ;
  410.              Inc (P.Index,NrOfSpaces) ;
  411.              Inc (P.Colnr,NrOfSpaces) ;
  412.              end
  413.      end ; { of with }
  414. end ;
  415.  
  416. {-----------------------------------------------------------------------------}
  417. { Insert a carriage return - line feed pair into the current workspace at     }
  418. { position P. If autoindent is on, the left margin of the current line is     }
  419. { determined, and the same number of spaces inserted at the beginning of the  }
  420. { new line.                                                                   }
  421. {-----------------------------------------------------------------------------}
  422.  
  423. procedure InsertCRLF (var P:Position) ;
  424.  
  425. var Counter,LeftMargin : word ;
  426.  
  427. begin
  428. with Workspace[CurrentWsnr] do
  429.      begin
  430.      { look for first non-space on current line }
  431.      LeftMargin := 1 ;
  432.      while (Buffer^[P.Index-P.Colnr+LeftMargin] = ' ') and
  433.            (LeftMargin <= P.Colnr) do
  434.            Inc (LeftMargin) ;
  435.     if LeftMargin > P.Colnr then LeftMargin := 1 ;
  436.     if Grow (P.Index,2)
  437.        then begin
  438.             Buffer^[P.Index] := CR ;
  439.             Buffer^[P.Index+1] := LF ;
  440.             Inc (P.Index,2) ;
  441.             Inc (P.Linenr) ;
  442.             P.Colnr := 1 ;
  443.             if Config.Setup.AutoIndent
  444.                then InsertSpaces (P,LeftMargin-1) ;
  445.             end ;
  446.      end ; { of with }
  447. end ;
  448.  
  449. {-----------------------------------------------------------------------------}
  450. { Redraws the entire screen including the status line                         }
  451. { The new screen contents are first written to an array in memory, and then   }
  452. { transferred to video memory by a call to MoveToScreen (line by line).       }
  453. {-----------------------------------------------------------------------------}
  454.  
  455. procedure RedrawScreen ;
  456.  
  457. var LineCounter             : byte ;
  458.     IndexCounter,ColCounter : word ;
  459.     BlockStart,BlockStop    : word ;
  460.     NormAttr,BlockAttr      : byte ;
  461.     ScreenChar              : ScreenElement ;
  462.     StatusLine              : string[ColsOnScreen] ;
  463.     NewDisplayLine          : array [1..ColsOnScreen] of word ;
  464.     TempStr                 : string[5] ;
  465.  
  466. begin
  467. with Workspace[CurrentWsnr] do
  468.      begin
  469.      { check if FirstVisiblePos needs to be adapted }
  470.      if (FirstVisiblePos.Linenr > CurPos.Linenr)
  471.         then
  472.           begin
  473.           { line number of CurPos is too low }
  474.           FirstVisiblePos := CurPos ;
  475.           Home(FirstVisiblePos) ;
  476.           end ;
  477.      if ((FirstVisiblePos.Linenr+NrOfTextLines) <= CurPos.Linenr)
  478.         then
  479.           begin
  480.           { line number of CurPos is too high }
  481.           if ((FirstVisiblePos.Linenr+2*NrOfTextLines) <= CurPos.Linenr)
  482.              then
  483.                begin
  484.                { difference is more than 1 screen }
  485.                FirstVisiblePos := CurPos ;
  486.                repeat
  487.                  LineUp (FirstVisiblePos) ;
  488.                until ((FirstVisiblePos.Linenr+NrOfTextLines) =
  489.                       (CurPos.Linenr + 1)) ;
  490.                end
  491.              else
  492.                begin
  493.                { difference is less than 1 screen }
  494.                while ((FirstVisiblePos.Linenr+NrOfTextLines) <=
  495.                       CurPos.Linenr) do
  496.                      begin
  497.                      LineDown (FirstVisiblePos) ;
  498.                      end ;
  499.                end ;
  500.           end ;
  501.      if FirstScreenCol > CurPos.Colnr
  502.         then
  503.           begin
  504.           { colum number of CurPos is too low }
  505.           Dec (FirstVisiblePos.Index,FirstVisiblePos.Colnr - CurPos.Colnr) ;
  506.           FirstVisiblePos.Colnr := CurPos.Colnr ;
  507.           FirstScreenCol := CurPos.Colnr ;
  508.           end ;
  509.      if (FirstScreenCol+ColsOnScreen) <= CurPos.Colnr
  510.         then
  511.           begin
  512.           { colum number of CurPos is too high }
  513.           FirstScreenCol := CurPos.Colnr - ColsOnScreen + 1 ;
  514.           while (FirstVisiblePos.Colnr < FirstScreenCol) and
  515.                 (Buffer^[FirstVisiblePos.Index] <> CR) do
  516.                 begin
  517.                 Inc (FirstVisiblePos.Index) ;
  518.                 Inc (FirstVisiblePos.Colnr) ;
  519.                 end ; { of while }
  520.           end ;
  521.      { set index of first and last characters to be displayed as block }
  522.      if (Mark <> Inactive)
  523.         then
  524.           begin
  525.           if Mark < CurPos.Index
  526.              then
  527.                begin
  528.                BlockStart := Mark ;
  529.                BlockStop := CurPos.Index ;
  530.                end
  531.              else
  532.                begin
  533.                BlockStart := CurPos.Index ;
  534.                BlockStop := Mark ;
  535.                end
  536.           end
  537.         else
  538.           begin
  539.           { do not show a block on the screen }
  540.           BlockStart := 0 ;
  541.           BlockStop := 0 ;
  542.           end ;
  543.      { Initialize working variables: }
  544.      { NormAttr contains attribute of normal characters on screen }
  545.      NormAttr := ScreenColorArray[Config.Setup.ScreenColors].NormAttr ;
  546.      { BlockAttr contains attribute of characters in block }
  547.      BlockAttr := ScreenColorArray[Config.Setup.ScreenColors].BlockAttr ;
  548.      { IndexCounter contains index of next character to be displayed }
  549.      IndexCounter := FirstVisiblePos.Index - FirstVisiblePos.Colnr + 1 ;
  550.      { initialise attribute of characters on screen }
  551.      if (IndexCounter > BlockStart) and (BlockStart <> 0)
  552.         then ScreenChar.Attribute := BlockAttr
  553.         else ScreenChar.Attribute := NormAttr ;
  554.      { write text lines to NewDisplay }
  555.      for LineCounter := 1 to NrOfTextLines do
  556.          begin
  557.          { skip to first character on line to be displayed (if there is one) }
  558.          ColCounter := 1 ;
  559.          while (ColCounter < FirstScreenCol) and
  560.                (Buffer^[IndexCounter] <> CR) and
  561.                (IndexCounter < BufferSize) do
  562.                begin
  563.                Inc (IndexCounter) ;
  564.                Inc (ColCounter) ;
  565.                end ;
  566.          { write a full screen line to NewDisplay }
  567.          for ColCounter := 1 to ColsOnScreen do
  568.              begin
  569.              ScreenChar.contents := Buffer^[IndexCounter] ;
  570.              if Config.Setup.DotsForSpaces and (ScreenChar.contents = ' ')
  571.                 then ScreenChar.contents := #250 ;
  572.              { set attribute (NormAttr or BlockAttr) }
  573.              if IndexCounter = BlockStop
  574.                 then ScreenChar.Attribute := NormAttr
  575.                 else if IndexCounter = BlockStart
  576.                         then ScreenChar.Attribute := BlockAttr ;
  577.              { if end of text line or of buffer is reached: display a space }
  578.              if (ScreenChar.contents = CR) or (IndexCounter = BufferSize)
  579.                 then ScreenChar.contents := ' '
  580.                 else Inc (IndexCounter) ;
  581.              { write 1 screen element to NewDisplayLine }
  582.              NewDisplayLine[ColCounter] := word(ScreenChar) ;
  583.              end ;
  584.          { display new line on screen }
  585.          MoveToScreen (NewDisplayLine[1],DisplayPtr^[LineCounter,1],
  586.                        ColsOnScreen*2) ;
  587.          { skip to next line }
  588.          if IndexCounter < BufferSize then Inc (IndexCounter) ;
  589.          while (Buffer^[IndexCounter-1] <> CR) and
  590.                (IndexCounter < BufferSize) do
  591.                Inc (IndexCounter) ;
  592.          if Buffer^[IndexCounter] = LF then Inc (IndexCounter) ;
  593.          end ; { of for }
  594.      if MessageRead
  595.         then
  596.           begin
  597.           { prepare status line }
  598.           StatusLine := BasicStatusLine ;
  599.           StatusLine[1] := Chr (64+CurrentWsnr) ;
  600.           TempStr := WordToString(CurPos.Linenr,0) ;
  601.           Move (TempStr[1],StatusLine[6],Length(TempStr)) ;
  602.           TempStr := WordToString(CurPos.Colnr,0) ;
  603.           Move (TempStr[1],StatusLine[14],Length(TempStr)) ;
  604.           if ChangesMade
  605.              then StatusLine[20] := '*' ;
  606.           Move (Name[1],StatusLine[22],Length(Name)) ;
  607.           StatusLine[56] := ' ' ;
  608.           if Config.Setup.WordWrapLength > Inactive
  609.              then Move (Status_Wrap[1],StatusLine[57],4) ;
  610.           if Config.Setup.Insertmode
  611.              then Move (Status_Ins[1],StatusLine[62],3) ;
  612.           if Config.Setup.AutoIndent
  613.              then Move (Status_Indent[1],StatusLine[66],6) ;
  614.           if MacroDefining <> Inactive
  615.              then Move (Status_Def[1],StatusLine[73],3) ;
  616.           TempStr := WordToString (BufferSize div OnePercent,3) ;
  617.           Move (TempStr[1],StatusLine[77],3) ;
  618.           { show status line on screen }
  619.           SetBottomline (StatusLine) ;
  620.           end ;
  621.      { set position of cursor }
  622.      OldCursorPosAttr := Hi (DisplayPtr^[WhereY,WhereX]) ;
  623.      CursorTo (CurPos.Colnr - FirstScreenCol + 1,
  624.                CurPos.Linenr - FirstVisiblePos.Linenr + 1) ;
  625.      end ; { of with }
  626. end ; { of procedure }
  627.  
  628. {-----------------------------------------------------------------------------}
  629. { Interactive change of the setup                                             }
  630. {-----------------------------------------------------------------------------}
  631.  
  632. procedure AlterSetup ;
  633.  
  634. var ConfigFile : file of ConfigBlock ;
  635.  
  636. begin
  637. SetCursor (Inactive) ;
  638. with Config.Setup do
  639.   begin
  640.   case Choose ('Display  Environment  File  Printer  Save-setup') of
  641.       'D' : case Choose ('Colors  cursorType  Dots-for-spaces') of
  642.               'C' : begin
  643.                     if ColorCard
  644.                        then begin
  645.                             if ScreenColors = NrOfColorSettings
  646.                                then Screencolors := 1
  647.                                else Inc (ScreenColors) ;
  648.                             end
  649.                        else begin
  650.                             if ScreenColors = 1
  651.                                then Screencolors := 2
  652.                                else Screencolors := 1 ;
  653.                             end ;
  654.                     TextAttr := ScreenColorArray[ScreenColors].NormAttr ;
  655.                     end ;
  656.               'T' : if Cursortype = NrOfCursorTypes
  657.                        then Cursortype := 1
  658.                        else Inc (Cursortype) ;
  659.               'D' : EnterBoolean (DotsForSpaces,'Display spaces as small dots?') ;
  660.               end ; { of case }
  661.       'E' : case Choose ('Keyclick  Bell  Wordwrap  Tabs  Autoindent  Insert') of
  662.               'K' : EnterBoolean (Keyclick,'Keyclick on?') ;
  663.               'B' : EnterBoolean (SoundBell,
  664.                                   'Sound bell on errors and warnings?') ;
  665.               'W' : EnterWord (WordWrapLength,
  666.                                'Line length for word wrap (0 = off): ',0,255) ;
  667.               'T' : Enterword (TabSpacing,'Tab spacing (0 = align): ',0,255) ;
  668.               'A' : EnterBoolean (AutoIndent,'Auto indent on?') ;
  669.               'I' : EnterBoolean (Insertmode,'Insert mode on?') ;
  670.               end ; { of case }
  671.       'F' : case Choose ('Exit-auto-save  Interval-auto-save  Backup-files') of
  672.               'E' : EnterBoolean (SaveOnExit,
  673.                                   'Save changed files on exiting AE?') ;
  674.               'I' : EnterWord (SaveInterval,
  675.                                'Interval for auto-save in minutes (0 = off): ',
  676.                                 0,1000) ;
  677.               'B' : EnterBoolean (MakeBAKfile,'Make .BAK file when saving?') ;
  678.               end ; { of case }
  679.       'P' : case Choose ('Page-length  Left-margin  Top-margin  page-Numbers') of
  680.               'P' : EnterWord (PageLength,
  681.                                'Lines per page for paged prints (0 = off): ',
  682.                                0,1000) ;
  683.               'L' : EnterWord (LeftMargin,'Left margin: ',0,240) ;
  684.               'T' : EnterWord (TopMargin,'Top margin: ',0,1000) ;
  685.               'N' : EnterBoolean (PrintPagenrs,'Print page numbers?') ;
  686.               end ; { of case }
  687.       'S' : begin
  688.             if Answer ('Save current setup?')
  689.                then
  690.                  begin
  691.                  Assign (ConfigFile,ConfigFilename) ;
  692.                  Rewrite (ConfigFile) ;
  693.                  Write (ConfigFile,Config) ;
  694.                  CheckDiskerror ;
  695.                  Close (ConfigFile) ;
  696.                  Message ('Setup saved as ' + ConfigFileName +
  697.                           ' in current directory') ;
  698.                  end ;
  699.             end ;
  700.       end ; { of case }
  701.   SetCursor (CursorType) ;
  702.   end ; { of with }
  703. end ;
  704.  
  705. {-----------------------------------------------------------------------------}
  706.  
  707. end.
  708.